package com.zshan.clinic.admin.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.zshan.clinic.admin.constant.Constants;
import com.zshan.clinic.admin.entity.medical.exam.ExamDetail;
import com.zshan.clinic.admin.entity.medical.field.MedicalFieldDetail;
import com.zshan.clinic.admin.entity.medical.rx.RxDrug;
import com.zshan.clinic.admin.entity.medical.rx.RxExt;
import com.zshan.clinic.admin.entity.medical.rx.RxInfusion;
import com.zshan.clinic.admin.entity.medical.rx.RxTcm;
import com.zshan.clinic.admin.entity.medical.rx.base.*;
import com.zshan.clinic.admin.entity.vo.DictFrequencyVo;
import com.zshan.clinic.admin.entity.vo.DictUsageVo;
import com.zshan.clinic.admin.entity.vo.StockDrugProfileDetailVo;
import com.zshan.clinic.admin.service.config.ClinicDictService;
import com.zshan.clinic.admin.service.config.MedicalFieldService;
import com.zshan.clinic.admin.service.config.ProjectFeeService;
import com.zshan.clinic.admin.service.stock.DrugProfileService;
import com.zshan.clinic.admin.service.stock.StockSupplyService;
import com.zshan.clinic.admin.util.RxUtil;
import com.zshan.clinic.common.constant.CommonConstant;
import com.zshan.clinic.common.enums.*;
import com.zshan.clinic.common.exception.BusinessFailException;
import com.zshan.clinic.common.util.decimal.BigDecimalUtils;
import com.zshan.clinic.common.util.json.JsonUtil;
import com.zshan.clinic.common.util.string.StringUtil;
import com.zshan.clinic.database.model.ClinicProjectFee;
import com.zshan.clinic.database.model.DictAcupoint;
import com.zshan.clinic.database.model.MedicalField;
import com.zshan.clinic.database.model.StockStorage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 病历验证功能类
 * @author lichen
 */
@Slf4j
public abstract class MedicalValidateService {

	/**
	 * 病历字段
	 */
	@Autowired
	private MedicalFieldService medicalFieldService;

	/**
	 * 项目信息
	 */
	@Autowired
	protected ProjectFeeService projectFeeService;

	/**
	 * 药品信息
	 */
	@Autowired
	protected DrugProfileService drugProfileService;

	/**
	 * 常量
	 */
	@Autowired
	private ClinicDictService clinicDictService;

	@Autowired
	private StockSupplyService stockSupplyService;


	/**
	 * 计算处方的价格
	 * @param clinicId
	 * @param rxList
	 */
	public void handleRxPrice(Long clinicId, List<RxBase> rxList) {
		if(CollectionUtils.isEmpty(rxList)){
			return;
		}
		// 初始化 4 个不同类型的列表
		List<RxDrug> drugList = new ArrayList<>();
		List<RxInfusion> infusionList = new ArrayList<>();
		List<RxExt> extList = new ArrayList<>();
		List<RxTcm> tcmList = new ArrayList<>();
		// 单次遍历
		for (RxBase rxBase : rxList) {
			// 根据 rxType 类型添加到对应的列表中
			if (RxTypeEnum.DRUG.getValue().equals(rxBase.getRxType())) {
				drugList.add((RxDrug) rxBase);
			} else if (RxTypeEnum.INFUSION.getValue().equals(rxBase.getRxType())) {
				infusionList.add((RxInfusion) rxBase);
			} else if (RxTypeEnum.EXT.getValue().equals(rxBase.getRxType())) {
				extList.add((RxExt) rxBase);
			} else if (RxTypeEnum.TCM.getValue().equals(rxBase.getRxType())) {
				tcmList.add((RxTcm) rxBase);
			}
		}
		if(!CollectionUtils.isEmpty(drugList) || !CollectionUtils.isEmpty(tcmList) || !CollectionUtils.isEmpty(infusionList)){
			StockStorage stockStorage = stockSupplyService.getDefaultStockStorage(clinicId);
			if(stockStorage == null){
				log.info(">>>>>>>>>>>没有查询到默认的药库不进行计算>>>>>>>>>>>");
				return;
			}
			Map<String,StockDrugProfileDetailVo> drugProfileMap = getDrugProfileList(clinicId,stockStorage.getStorageId(),drugList,infusionList,tcmList);
			if(!CollectionUtils.isEmpty(drugProfileMap)){
				if(!CollectionUtils.isEmpty(drugList)){
					//成药
					handleDrugPrice(drugList,stockStorage.getStorageId(),drugProfileMap);
				}
				if(!CollectionUtils.isEmpty(tcmList)){
					//中药
					handleTcmPrice(tcmList,stockStorage.getStorageId(),drugProfileMap);
				}
				if(!CollectionUtils.isEmpty(infusionList)){
					//输液
					handleInfusionPrice(infusionList,stockStorage.getStorageId(),drugProfileMap);
				}
			}

		}
		if(!CollectionUtils.isEmpty(extList)){
			List<ClinicProjectFee> projectFeeList  = getProjectFeeList(extList);
			if(CollectionUtils.isEmpty(projectFeeList)){
				throw new BusinessFailException("请先添加项目！");
			}
			// 将 projectFeeList 转换为 Map<Long, ClinicProjectFee>，其中 projectId 是键
			Map<Long, ClinicProjectFee> projectFeeMap = projectFeeList.stream()
					.collect(Collectors.toMap(ClinicProjectFee::getProjectId, projectFee -> projectFee));
			//外治
			handleExtPrice(extList,projectFeeMap);
		}

	}

	/**
	 * 计算外治项目的价格
	 * @param extList
	 * @param projectFeeMap
	 */
	public void handleExtPrice(List<RxExt> extList, Map<Long, ClinicProjectFee> projectFeeMap) {
		for(RxExt rxExt : extList){
			RxExtInfo extInfo = rxExt.getExtInfo();
			if(extInfo == null){
				continue;
			}
			ClinicProjectFee clinicProjectFee = projectFeeMap.get(extInfo.getProjectId());
			if(clinicProjectFee == null){
				continue;
			}
			BeanUtils.copyProperties(clinicProjectFee,extInfo);
			//总出库量
			Integer totalOutQty = extInfo.getTotalOutQty();
			//计算总出库量
			if(totalOutQty == null || totalOutQty <= CommonConstant.DEFAULT_0){
				continue;
			}
			extInfo.setSubtotal(totalOutQty * clinicProjectFee.getPrice());
			rxExt.setTotalAmount(extInfo.getSubtotal());
		}
	}

	/**
	 * 计算输液处方的价格
	 * @param infusionList
	 * @param drugProfileMap
	 */
	public void handleInfusionPrice(List<RxInfusion> infusionList, Long defaultStorageId,Map<String, StockDrugProfileDetailVo> drugProfileMap) {
		for(RxInfusion rxInfusion : infusionList){
			if(PayStatusEnum.PAID.getValue().equals(rxInfusion.getPayStatus())){
				//已收费的项目不处理
				continue;
			}
			List<RxInfusionGroup> groupList = rxInfusion.getGroupList();
			if(CollectionUtils.isEmpty(groupList)){
				continue;
			}
			Integer totalAmount = CommonConstant.DEFAULT_0;
			for(RxInfusionGroup rxInfusionGroup : groupList){
				List<RxInfusionGroupDetail> detailList = rxInfusionGroup.getDetailList();
				if(CollectionUtils.isEmpty(detailList)){
					continue;
				}
				Integer subtotal = CommonConstant.DEFAULT_0;
				for(RxInfusionGroupDetail groupDetail : detailList){
					//检查药品
					Long storageId = rxInfusion.getStorageId();
					if(StringUtil.isBlank(storageId)){
						storageId = defaultStorageId;
					}
					String key = storageId + "_" + groupDetail.getDrugId();
					StockDrugProfileDetailVo stockDrugProfile = drugProfileMap.get(key);
					if(stockDrugProfile == null){
						continue;
					}
					//更新药品的信息
					BeanUtils.copyProperties(stockDrugProfile,groupDetail);
					//剂量用药品的最小单位
					groupDetail.setDosageUnit(stockDrugProfile.getMinPackUnit());
					groupDetail.setDosageUnitText(stockDrugProfile.getMinPackUnitText());
					//总出库量
					Integer totalOutQty = groupDetail.getTotalOutQty();
					if(totalOutQty == null || totalOutQty <= CommonConstant.DEFAULT_0){
						continue;
					}
					groupDetail.setSubtotal(RxUtil.calculatePrice(totalOutQty,stockDrugProfile.getMinPackQty(),stockDrugProfile.getIsSplit(),stockDrugProfile.getPrice(),stockDrugProfile.getSplitPrice()));
					subtotal = subtotal + groupDetail.getSubtotal();
				}
				rxInfusionGroup.setSubtotal(subtotal);
				totalAmount = totalAmount + rxInfusionGroup.getSubtotal();
			}
			rxInfusion.setTotalAmount(totalAmount);
		}
	}

	/**
	 * 计算中药处方的价格
	 * @param tcmList
	 * @param drugProfileMap
	 */
	public void handleTcmPrice(List<RxTcm> tcmList, Long defaultStorageId,Map<String, StockDrugProfileDetailVo> drugProfileMap) {
		for(RxTcm rxTcm : tcmList){
			if(PayStatusEnum.PAID.getValue().equals(rxTcm.getPayStatus())){
				//已收费的项目不处理
				continue;
			}
			RxTcmInfo rxTcmInfo = rxTcm.getTcmInfo();
			List<RxTcmDetail> detailList = rxTcmInfo.getDetailList();
			if(CollectionUtils.isEmpty(detailList)){
				continue;
			}
			Integer totalAmount = CommonConstant.DEFAULT_0;
			for(RxTcmDetail rxTcmDetail : detailList){
				//检查药品
				Long storageId = rxTcm.getStorageId();
				if(StringUtil.isBlank(storageId)){
					storageId = defaultStorageId;
				}
				String key = storageId + "_" + rxTcmDetail.getDrugId();
				StockDrugProfileDetailVo stockDrugProfile = drugProfileMap.get(key);
				if(stockDrugProfile == null){
					continue;
				}
				//更新药品的信息
				BeanUtils.copyProperties(stockDrugProfile,rxTcmDetail);
				//剂量用药品的最小单位
				rxTcmDetail.setDosageUnit(stockDrugProfile.getPackUnit());
				rxTcmDetail.setDosageUnitText(stockDrugProfile.getPackUnitText());
				//总出库量
				Integer totalOutQty = rxTcmDetail.getTotalOutQty();
				if(totalOutQty == null || totalOutQty <= CommonConstant.DEFAULT_0){
					continue;
				}
				//总价格=单价*总出库量
				rxTcmDetail.setSubtotal(stockDrugProfile.getPrice() * totalOutQty);
				rxTcmInfo.setSubtotal(rxTcmDetail.getSubtotal());
				totalAmount = totalAmount + rxTcmDetail.getSubtotal();
			}
			rxTcm.setTotalAmount(totalAmount);
		}
	}

	/**
	 * 计算成药处方的价格
	 * @param drugList
	 * @param drugProfileMap
	 */
	public void handleDrugPrice(List<RxDrug> drugList, Long defaultStorageId,Map<String, StockDrugProfileDetailVo> drugProfileMap) {
		for(RxDrug rxDrug : drugList){
			if(PayStatusEnum.PAID.getValue().equals(rxDrug.getPayStatus())){
				//已收费的项目不处理
				continue;
			}
			List<RxDrugDetail> detailList = rxDrug.getDetailList();
			if(CollectionUtils.isEmpty(detailList)){
				continue;
			}
			Integer totalAmount = CommonConstant.DEFAULT_0;
			for(RxDrugDetail rxDrugDetail : detailList){
				Long storageId = rxDrug.getStorageId();
				if(StringUtil.isBlank(storageId)){
					storageId = defaultStorageId;
				}
				String key = storageId + "_" + rxDrugDetail.getDrugId();
				StockDrugProfileDetailVo stockDrugProfile = drugProfileMap.get(key);
				if(stockDrugProfile == null){
					continue;
				}
				//更新药品的信息
				BeanUtils.copyProperties(stockDrugProfile,rxDrugDetail);
				//剂量用药品的最小单位
				rxDrugDetail.setDosageUnit(stockDrugProfile.getMinPackUnit());
				rxDrugDetail.setDosageUnitText(stockDrugProfile.getMinPackUnitText());
				//总出库量
				Integer totalOutQty = rxDrugDetail.getTotalOutQty();
				if(totalOutQty == null || totalOutQty <= CommonConstant.DEFAULT_0){
					continue;
				}
				//计算价格
				rxDrugDetail.setSubtotal(RxUtil.calculatePrice(totalOutQty,stockDrugProfile.getMinPackQty(),stockDrugProfile.getIsSplit(),stockDrugProfile.getPrice(),stockDrugProfile.getSplitPrice()));
				totalAmount = totalAmount + rxDrugDetail.getSubtotal();
			}
			rxDrug.setTotalAmount(totalAmount);
		}
	}


	/**
	 * 获取处方中配置的所有药品的ID
	 * @param rxList
	 * @return
	 */
	public List<Long> getDrugIdListByRx(List<RxBase> rxList){
		// 初始化 4 个不同类型的列表
		List<RxDrug> drugList = new ArrayList<>();
		List<RxInfusion> infusionList = new ArrayList<>();
		List<RxTcm> tcmList = new ArrayList<>();
		// 单次遍历
		for (RxBase rxBase : rxList) {
			// 根据 rxType 类型添加到对应的列表中
			if (RxTypeEnum.DRUG.getValue().equals(rxBase.getRxType())) {
				drugList.add((RxDrug) rxBase);
			} else if (RxTypeEnum.INFUSION.getValue().equals(rxBase.getRxType())) {
				infusionList.add((RxInfusion) rxBase);
			} else if (RxTypeEnum.TCM.getValue().equals(rxBase.getRxType())) {
				tcmList.add((RxTcm) rxBase);
			}
		}
		return getDrugIdList(drugList,infusionList,tcmList);
	}


	public List<Long> getDrugIdList(List<RxDrug> drugList, List<RxInfusion> infusionList, List<RxTcm> tcmList) {
		List<Long> drugIdList = new ArrayList<>();
		if(!CollectionUtils.isEmpty(drugList)){
			for(RxDrug rxDrug : drugList){
				List<RxDrugDetail> detailList = rxDrug.getDetailList();
				if(!CollectionUtils.isEmpty(detailList)){
					for(RxDrugDetail detail : detailList){
						drugIdList.add(detail.getDrugId());
					}
				}
			}
		}
		if(!CollectionUtils.isEmpty(infusionList)){
			for(RxInfusion rxInfusion : infusionList){
				List<RxInfusionGroup> groupList = rxInfusion.getGroupList();
				if(!CollectionUtils.isEmpty(groupList)){
					for(RxInfusionGroup groupDTO : groupList){
						List<RxInfusionGroupDetail> detailList = groupDTO.getDetailList();
						if(!CollectionUtils.isEmpty(detailList)){
							for(RxInfusionGroupDetail detail : detailList){
								drugIdList.add(detail.getDrugId());
							}
						}
					}
				}
			}
		}
		if(!CollectionUtils.isEmpty(tcmList)){
			for(RxTcm rxTcm : tcmList){
				RxTcmInfo rxTcmInfo = rxTcm.getTcmInfo();
				if(rxTcmInfo != null){
					List<RxTcmDetail> detailList = rxTcmInfo.getDetailList();
					if(!CollectionUtils.isEmpty(detailList)){
						for(RxTcmDetail detail : detailList){
							drugIdList.add(detail.getDrugId());
						}
					}
				}
			}
		}
		return drugIdList;
	}

	/**
	 * 处方的json转实体
	 * @param rxList
	 * @return
	 */
	public List<RxBase> handleRxList(List<RxBase> rxList) {
		if(CollectionUtils.isEmpty(rxList)){
			return Collections.emptyList();
		}
		List<RxBase> returnList = new ArrayList<>();
		for(RxBase rxBase : rxList){
			String rxType = rxBase.getRxType();
			if(RxTypeEnum.DRUG.getValue().equals(rxType)){
				RxDrug rxDrug = new RxDrug();
				BeanUtils.copyProperties(rxBase,rxDrug);
				rxDrug.setDetailList(JsonUtil.json2Obj(rxBase.getRxJson(),new TypeReference<List<RxDrugDetail>>() {}));
				returnList.add(rxDrug);
			}else if (RxTypeEnum.INFUSION.getValue().equals(rxType)){
				RxInfusion rxInfusion = new RxInfusion();
				BeanUtils.copyProperties(rxBase,rxInfusion);
				rxInfusion.setGroupList(JsonUtil.json2Obj(rxBase.getRxJson(),new TypeReference<List<RxInfusionGroup>>() {}));
				returnList.add(rxInfusion);
			}else if (RxTypeEnum.TCM.getValue().equals(rxType)){
				RxTcm rxTcm = new RxTcm();
				BeanUtils.copyProperties(rxBase,rxTcm);
				rxTcm.setTcmInfo(JsonUtil.json2Obj(rxBase.getRxJson(),new TypeReference<RxTcmInfo>() {}));
				returnList.add(rxTcm);
			}else if (RxTypeEnum.EXT.getValue().equals(rxType)){
				RxExt rxExt = new RxExt();
				BeanUtils.copyProperties(rxBase,rxExt);
				rxExt.setExtInfo(JsonUtil.json2Obj(rxBase.getRxJson(),new TypeReference<RxExtInfo>() {}));
				returnList.add(rxExt);
			}
		}
		returnList.sort(Comparator.comparing(RxBase::getRxType));
		return returnList;
	}

	/**
	 * 校验处方数据
	 * @param isMedical 是否门诊（门诊需要验证库存）
	 * @param rxList
	 */
	public void validateMedicalRx(String isMedical,Long clinicId,List<RxBase> rxList){
		if(CollectionUtils.isEmpty(rxList)){
			throw new BusinessFailException("请先添加处方！");
		}
		// 初始化 4 个不同类型的列表
		List<RxDrug> drugList = new ArrayList<>();
		List<RxInfusion> infusionList = new ArrayList<>();
		List<RxExt> extList = new ArrayList<>();
		List<RxTcm> tcmList = new ArrayList<>();
		// 单次遍历
		for (RxBase rxBase : rxList) {
			// 根据 rxType 类型添加到对应的列表中
			if (RxTypeEnum.DRUG.getValue().equals(rxBase.getRxType())) {
				drugList.add((RxDrug) rxBase);
			} else if (RxTypeEnum.INFUSION.getValue().equals(rxBase.getRxType())) {
				infusionList.add((RxInfusion) rxBase);
			} else if (RxTypeEnum.EXT.getValue().equals(rxBase.getRxType())) {
				extList.add((RxExt) rxBase);
			} else if (RxTypeEnum.TCM.getValue().equals(rxBase.getRxType())) {
				tcmList.add((RxTcm) rxBase);
			}
		}
		//是否为门诊
		boolean medicalFlag = YesOrNoEnum.YES.getValue().equals(isMedical);
		if(!CollectionUtils.isEmpty(drugList) || !CollectionUtils.isEmpty(tcmList) || !CollectionUtils.isEmpty(infusionList)){
			StockStorage stockStorage = stockSupplyService.getDefaultStockStorage(clinicId);
			if(stockStorage == null){
				throw new BusinessFailException("请先配置药库！");
			}
			Map<String,StockDrugProfileDetailVo> drugProfileMap = getDrugProfileList(clinicId,stockStorage.getStorageId(),drugList,infusionList,tcmList);
			if(CollectionUtils.isEmpty(drugProfileMap)){
				throw new BusinessFailException("请先添加药品！");
			}
			if(!CollectionUtils.isEmpty(drugList)){
				//成药
				validateDrugList(medicalFlag,drugList,stockStorage.getStorageId(),drugProfileMap);
			}
			if(!CollectionUtils.isEmpty(tcmList)){
				//中药
				validateTcmList(medicalFlag,tcmList,stockStorage.getStorageId(),drugProfileMap);
			}
			if(!CollectionUtils.isEmpty(infusionList)){
				//输液
				validateInfusionList(medicalFlag,infusionList,stockStorage.getStorageId(),drugProfileMap);
			}
		}
		if(!CollectionUtils.isEmpty(extList)){
			List<ClinicProjectFee> projectFeeList  = getProjectFeeList(extList);
			if(CollectionUtils.isEmpty(projectFeeList)){
				throw new BusinessFailException("请先添加项目！");
			}
			// 将 projectFeeList 转换为 Map<Long, ClinicProjectFee>，其中 projectId 是键
			Map<Long, ClinicProjectFee> projectFeeMap = projectFeeList.stream()
					.collect(Collectors.toMap(ClinicProjectFee::getProjectId, projectFee -> projectFee));
			//外治
			validateExtList(medicalFlag,extList,projectFeeMap);
		}
	}

	/**
	 *
	 * @param defaultStorageId 默认的药库ID
	 * @param drugList
	 * @param infusionList
	 * @param tcmList
	 * @return
	 */
	public Map<Long, List<Long>> getDrugIdMap(Long defaultStorageId,List<RxDrug> drugList, List<RxInfusion> infusionList, List<RxTcm> tcmList) {
		Map<Long, List<Long>> storageMap = new HashMap<>();
		if(!CollectionUtils.isEmpty(drugList)){
			for(RxDrug rxDrug : drugList){
				List<RxDrugDetail> detailList = rxDrug.getDetailList();
				if(!CollectionUtils.isEmpty(detailList)){
					for(RxDrugDetail detail : detailList){
						Long storageId = rxDrug.getStorageId();
						if(StringUtil.isBlank(storageId)){
							storageId = defaultStorageId;
						}
						addToStorageMap(storageMap,storageId,detail.getDrugId());
					}
				}
			}
		}
		if(!CollectionUtils.isEmpty(infusionList)){
			for(RxInfusion rxInfusion : infusionList){
				List<RxInfusionGroup> groupList = rxInfusion.getGroupList();
				if(!CollectionUtils.isEmpty(groupList)){
					for(RxInfusionGroup groupDTO : groupList){
						List<RxInfusionGroupDetail> detailList = groupDTO.getDetailList();
						if(!CollectionUtils.isEmpty(detailList)){
							for(RxInfusionGroupDetail detail : detailList){
								Long storageId = rxInfusion.getStorageId();
								if(StringUtil.isBlank(storageId)){
									storageId = defaultStorageId;
								}
								addToStorageMap(storageMap,storageId,detail.getDrugId());
							}
						}
					}
				}
			}
		}
		if(!CollectionUtils.isEmpty(tcmList)){
			for(RxTcm rxTcm : tcmList){
				RxTcmInfo rxTcmInfo = rxTcm.getTcmInfo();
				if(rxTcmInfo != null){
					List<RxTcmDetail> detailList = rxTcmInfo.getDetailList();
					if(!CollectionUtils.isEmpty(detailList)){
						for(RxTcmDetail detail : detailList){
							Long storageId = rxTcm.getStorageId();
							if(StringUtil.isBlank(storageId)){
								storageId = defaultStorageId;
							}
							addToStorageMap(storageMap,storageId,detail.getDrugId());
						}
					}
				}
			}
		}
		return storageMap;
	}

	private void addToStorageMap(Map<Long, List<Long>> storageMap, Long storageId, Long drugId) {
		storageMap.putIfAbsent(storageId, new ArrayList<>());
		storageMap.get(storageId).add(drugId);
	}

	/**
	 * 获取药品信息
	 * @param drugList
	 * @param infusionList
	 * @param tcmList
	 * @return
	 */
	public Map<String,StockDrugProfileDetailVo> getDrugProfileList(Long clinicId, Long defaultStorageId,List<RxDrug> drugList, List<RxInfusion> infusionList, List<RxTcm> tcmList) {
		Map<Long, List<Long>> drugIdList = getDrugIdMap(defaultStorageId, drugList, infusionList, tcmList);
		Map<String, StockDrugProfileDetailVo> drugMap = new HashMap<>();
		drugIdList.forEach((storageId, drugIds) -> {
			List<StockDrugProfileDetailVo> list =
					drugProfileService.getDrugRxStorageList(clinicId, storageId, drugIds);
			if (list == null) {
				return;
			}
			list.stream()
					.filter(vo -> vo.getDrugId() != null)
					.forEach(vo -> {
						String key = storageId + "_" + vo.getDrugId();
						drugMap.put(key, vo);
					});
		});
		return drugMap;
	}




	public List<ClinicProjectFee> getProjectFeeList(List<RxExt> extList) {
		List<Long> projectIdList = new ArrayList<>();
		if(!CollectionUtils.isEmpty(extList)){
			for(RxExt rxExt : extList){
				RxExtInfo extInfo = rxExt.getExtInfo();
				projectIdList.add(extInfo.getProjectId());
			}
		}
		if(CollectionUtils.isEmpty(projectIdList)){
			return null;
		}
		return projectFeeService.getEnabledClinicProjectFeeList(projectIdList,ProjectCategoryEnum.getExtList());
	}


	/**
	 * 校验中药处方
	 * @param tcmList
	 */
	public void validateTcmList(boolean isMedical,List<RxTcm> tcmList,Long defaultStorageId,Map<String, StockDrugProfileDetailVo> drugProfileMap) {
		int sort = CommonConstant.DEFAULT_0;
		for(RxTcm rxTcm : tcmList){
			sort = sort + CommonConstant.DEFAULT_1;
			if(StringUtil.isBlank(rxTcm.getRxName())){
				rxTcm.setRxName(String.format(Constants.DEFAULT_RX_TCM_NAME,StringUtil.toChinese(sort)));
			}
			if(isMedical && StringUtil.isBlank(rxTcm.getStorageId())){
				throw new BusinessFailException("请先选择药库！");
			}
			RxTcmInfo rxTcmInfo = rxTcm.getTcmInfo();
			List<RxTcmDetail> detailList = rxTcmInfo.getDetailList();
			if(CollectionUtils.isEmpty(detailList)){
				throw new BusinessFailException("至少添加一个药品！");
			}
			//频率 一天三次
			String frequencyCode = rxTcmInfo.getFrequencyCode();
			if(isMedical || StringUtil.isNotBlank(frequencyCode)){
				if(StringUtil.isBlank(frequencyCode)){
					throw new BusinessFailException("频率不能为空");
				}
				DictFrequencyVo dictFrequencyVo = clinicDictService.getCacheFrequency(frequencyCode);
				if(dictFrequencyVo == null){
					throw new BusinessFailException("频率不存在");
				}
				rxTcmInfo.setFrequencyCodeText(dictFrequencyVo.getFrequencyName());
				rxTcmInfo.setCycleUnit(dictFrequencyVo.getCycleUnit());
				rxTcmInfo.setCycleUnitText(CycleUnitEnum.getText(dictFrequencyVo.getCycleUnit()));
			}
			//每日剂量  1日1剂
			String dailyDosage = rxTcmInfo.getDailyDosage();
			//单个周期内的喝几剂 ，比如说一日一剂就代表 1
			BigDecimal dosage = new BigDecimal(0);
			if(isMedical || StringUtil.isNotBlank(dailyDosage)){
				if(StringUtil.isBlank(dailyDosage)){
					throw new BusinessFailException("每日剂量不能为空");
				}
				if(!TcmDailyDosageEnum.isValue(dailyDosage)){
					throw new BusinessFailException("每日剂量错误");
				}
				dosage = TcmDailyDosageEnum.getDosage(dailyDosage);
			}
			//周期  7天
			Integer cycle = rxTcmInfo.getCycle();
			if(isMedical || cycle != null){
				if(cycle == null || cycle <= CommonConstant.DEFAULT_0){
					throw new BusinessFailException("用药周期必须大于"+ CommonConstant.DEFAULT_0);
				}
				//总剂量
				rxTcmInfo.setTotalDoses(BigDecimalUtils.formatInt(BigDecimalUtils.multiply(dosage,new BigDecimal(cycle))));
			}
			//用法 煎服
			String usageCode = rxTcmInfo.getUsageCode();
			if(isMedical || StringUtil.isNotBlank(usageCode)){
				if(StringUtil.isBlank(usageCode)){
					throw new BusinessFailException("用法不能为空");
				}
				DictUsageVo dictUsageVo = clinicDictService.getUsageValue(RxTypeEnum.TCM.getValue(), usageCode);
				if(dictUsageVo == null){
					throw new BusinessFailException("用法错误");
				}
				rxTcmInfo.setUsageCodeText(dictUsageVo.getUsageName());
			}
			//单次喝多少毫升
			String singleDosage = rxTcmInfo.getSingleDosage();
			if(isMedical || StringUtil.isNotBlank(singleDosage)){
				if(StringUtil.isBlank(singleDosage)){
					throw new BusinessFailException("每次剂量不能为空");
				}
				if(!TcmSingleDosageEnum.isValue(singleDosage)){
					throw new BusinessFailException("每次剂量错误");
				}
			}

//                if(StringUtil.isNotBlank(templateRxTcmDTO.getRemark())){
//                    boolean remarkValue = clinicDictService.isRemarkValue(RxTypeEnum.TCM.getValue(), templateRxTcmDTO.getRemark());
//                    if(!remarkValue){
//                        throw new BusinessFailException("中药处方备注错误");
//                    }
//                }
			Integer totalAmount = CommonConstant.DEFAULT_0;
			for(RxTcmDetail rxTcmDetail : detailList){
				//检查药品
				Long storageId = rxTcm.getStorageId();
				if(StringUtil.isBlank(storageId)){
					storageId = defaultStorageId;
				}
				String key = storageId + "_" + rxTcmDetail.getDrugId();
				StockDrugProfileDetailVo stockDrugProfile = drugProfileMap.get(key);
				if(stockDrugProfile == null){
					throw new BusinessFailException("药品不存在");
				}
				BeanUtils.copyProperties(stockDrugProfile,rxTcmDetail);
				rxTcmDetail.setDosageUnit(stockDrugProfile.getPackUnit());
				rxTcmDetail.setDosageUnitText(stockDrugProfile.getPackUnitText());
				rxTcmDetail.setTotalOutQtyUnit(stockDrugProfile.getPackUnit());
				rxTcmDetail.setTotalOutQtyUnitText(stockDrugProfile.getPackUnitText());
				//药品的单次用量
				BigDecimal drugDosage = rxTcmDetail.getDosage();
				if(isMedical || drugDosage != null){
					if(drugDosage == null || BigDecimalUtils.lt(drugDosage, BigDecimal.ZERO)){
						throw new BusinessFailException("药品用量必须大于"+ CommonConstant.DEFAULT_0);
					}
					//总剂数*每剂的数量 一共5剂，每剂10g
					if(rxTcmInfo.getTotalDoses() != null){
						rxTcmDetail.setTotalOutQty(
								BigDecimalUtils.formatInt(BigDecimalUtils.multiply(new BigDecimal(rxTcmInfo.getTotalDoses()), drugDosage))
						);
						//总价格=单价*总出库量
						rxTcmDetail.setSubtotal(stockDrugProfile.getPrice() * rxTcmDetail.getTotalOutQty());
						rxTcmInfo.setSubtotal(rxTcmDetail.getSubtotal());
						totalAmount = totalAmount + rxTcmDetail.getSubtotal();
					}
				}
				if(StringUtil.isNotBlank(rxTcmDetail.getDecotionMethod())){
					if(!DecotionMethodEnum.isValue(rxTcmDetail.getDecotionMethod())){
						throw new BusinessFailException("煎法错误！");
					}
				}
//				if(YesOrNoEnum.YES.getValue().equals(isMedical)){
//					//门诊需要验证库存
//					if(stockDrugProfile.getStockQty() < rxTcmDetail.getTotalOutQty()){
//						throw new BusinessFailException(stockDrugProfile.getDrugName()+"库存不足！");
//					}
//				}
			}
			rxTcm.setTotalAmount(totalAmount);
		}
	}

	/**
	 * 校验外治处方
	 * @param extList
	 */
	public void validateExtList(boolean isMedical,List<RxExt> extList,Map<Long, ClinicProjectFee> projectFeeMap) {
		int sort = CommonConstant.DEFAULT_0;
		for(RxExt rxExt : extList){
			sort = sort + CommonConstant.DEFAULT_1;
			if(StringUtil.isBlank(rxExt.getRxName())){
				rxExt.setRxName(String.format(Constants.DEFAULT_RX_EXT_NAME,StringUtil.toChinese(sort)));
			}
			RxExtInfo extInfo = rxExt.getExtInfo();
			if(extInfo == null){
				throw new BusinessFailException("至少选择一个项目！");
			}
			ClinicProjectFee clinicProjectFee = projectFeeMap.get(extInfo.getProjectId());
			if(clinicProjectFee == null){
				throw new BusinessFailException("项目不存在");
			}
			if(!ProjectCategoryEnum.EXT.getValue().equals(clinicProjectFee.getProjectCategory())){
				throw new BusinessFailException("项目类型错误");
			}
			BeanUtils.copyProperties(clinicProjectFee,extInfo);
			extInfo.setTotalOutQtyUnit(clinicProjectFee.getUnit());
			extInfo.setTotalOutQtyUnitText(clinicProjectFee.getUnitText());
			//频率 一天一次
			String frequencyCode = extInfo.getFrequencyCode();
			//频率对应的周期内的次数，一天三次对应的就是3
			Integer frequencyTimes = 0;
			if(isMedical || StringUtil.isNotBlank(frequencyCode)){
				if(StringUtil.isBlank(frequencyCode)){
					throw new BusinessFailException("频率不能为空");
				}
				DictFrequencyVo dictFrequencyVo = clinicDictService.getCacheFrequency(frequencyCode);
				if(dictFrequencyVo == null){
					throw new BusinessFailException("频率不存在");
				}
				extInfo.setFrequencyCodeText(dictFrequencyVo.getFrequencyName());
				extInfo.setCycleUnit(dictFrequencyVo.getCycleUnit());
				extInfo.setCycleUnitText(CycleUnitEnum.getText(dictFrequencyVo.getCycleUnit()));
				frequencyTimes = dictFrequencyVo.getFrequencyTimes();
			}
			//周期 7天
			Integer cycle = extInfo.getCycle();
			if(isMedical || cycle != null){
				if(cycle == null || cycle <= CommonConstant.DEFAULT_0){
					throw new BusinessFailException("周期必须大于"+ CommonConstant.DEFAULT_0);
				}
			}
			//穴位明细
			List<RxExtDetail> detailList = extInfo.getDetailList();
			//需要计费的穴位数量
			int acupointCount = CommonConstant.DEFAULT_0;
			if(!CollectionUtils.isEmpty(detailList)){
				for(RxExtDetail detail : detailList){
					DictAcupoint dictAcupoint = clinicDictService.getCacheAcupoint(detail.getAcupointCode());
					if(dictAcupoint == null){
						throw new BusinessFailException("穴位错误");
					}
					if(StringUtil.isBlank(detail.getSideType())){
						throw new BusinessFailException("请选择穴位侧别");
					}
					if(!AcupointSideTypeEnum.isValue(detail.getSideType())){
						throw new BusinessFailException("穴位侧别错误");
					}
					if(AcupointSideTypeEnum.both.getValue().equals(detail.getSideType())){
						acupointCount = acupointCount + CommonConstant.DEFAULT_2;
					}else {
						acupointCount = acupointCount + CommonConstant.DEFAULT_1;
					}
					detail.setAcupointName(dictAcupoint.getAcupointText());
				}
			}
			if(isMedical || !CollectionUtils.isEmpty(detailList)){
				if(ProjectChargeTypeEnum.ACUPOINT.getValue().equals(clinicProjectFee.getChargeType())){
					if(CollectionUtils.isEmpty(detailList)){
						throw new BusinessFailException("至少选择一个穴位！");
					}
					//按照穴位收费 次数*周期  一天3次，周期5天，5个穴位 （3*5*5）
					extInfo.setTotalOutQty(frequencyTimes * extInfo.getCycle() * acupointCount);
				}else {
					//按照项目收费 次数*周期  一天3次，周期5天 （3*5）
					extInfo.setTotalOutQty(frequencyTimes * extInfo.getCycle());
				}
				extInfo.setSubtotal(extInfo.getTotalOutQty() * clinicProjectFee.getPrice());
				rxExt.setTotalAmount(extInfo.getSubtotal());
			}
		}
	}

	/**
	 * 校验输液处方
	 * @param infusionList
	 */
	public void validateInfusionList(boolean isMedical,List<RxInfusion> infusionList,Long defaultStorageId,Map<String, StockDrugProfileDetailVo> drugProfileMap) {
		int sort = CommonConstant.DEFAULT_0;
		for(RxInfusion rxInfusion : infusionList){
			sort = sort + CommonConstant.DEFAULT_1;
			if(StringUtil.isBlank(rxInfusion.getRxName())){
				rxInfusion.setRxName(String.format(Constants.DEFAULT_RX_INFUSION_NAME,StringUtil.toChinese(sort)));
			}
			if(isMedical && StringUtil.isBlank(rxInfusion.getStorageId())){
				throw new BusinessFailException("请先选择药库！");
			}
			List<RxInfusionGroup> groupList = rxInfusion.getGroupList();
			if(CollectionUtils.isEmpty(groupList)){
				throw new BusinessFailException("至少添加一个输液组！");
			}
			int groupSort = CommonConstant.DEFAULT_0;
			Integer totalAmount = CommonConstant.DEFAULT_0;
			for(RxInfusionGroup rxInfusionGroup : groupList){
				List<RxInfusionGroupDetail> detailList = rxInfusionGroup.getDetailList();
				if(CollectionUtils.isEmpty(detailList)){
					throw new BusinessFailException("至少添加一个药品！");
				}
				groupSort = groupSort + CommonConstant.DEFAULT_1;
				if(StringUtil.isBlank(rxInfusionGroup.getGroupName())){
					rxInfusionGroup.setGroupName(String.format(Constants.DEFAULT_RX_INFUSION_GROUP_NAME,StringUtil.toChinese(sort)));
				}
				//用法 静脉滴注
				String usageCode = rxInfusionGroup.getUsageCode();
				if(isMedical || StringUtil.isNotBlank(usageCode)){
					if(StringUtil.isBlank(usageCode)){
						throw new BusinessFailException("用法不能为空");
					}
					DictUsageVo dictUsageVo = clinicDictService.getUsageValue(RxTypeEnum.INFUSION.getValue(),usageCode);
					if(dictUsageVo == null){
						throw new BusinessFailException("用法错误");
					}
					rxInfusionGroup.setUsageCodeText(dictUsageVo.getUsageName());
				}
				//频率 一天一次
				String frequencyCode = rxInfusionGroup.getFrequencyCode();
				if(isMedical || StringUtil.isNotBlank(frequencyCode)){
					if(StringUtil.isBlank(frequencyCode)){
						throw new BusinessFailException("频率不能为空");
					}
					DictFrequencyVo dictFrequencyVo = clinicDictService.getCacheFrequency(frequencyCode);
					if(dictFrequencyVo == null){
						throw new BusinessFailException("频率不存在");
					}
					rxInfusionGroup.setFrequencyCodeText(dictFrequencyVo.getFrequencyName());
					rxInfusionGroup.setCycleUnit(dictFrequencyVo.getCycleUnit());
					rxInfusionGroup.setCycleUnitText(CycleUnitEnum.getText(dictFrequencyVo.getCycleUnit()));
				}
				//周期  7天
				Integer cycle = rxInfusionGroup.getCycle();
				if(isMedical || cycle != null){
					if(rxInfusionGroup.getCycle() == null || rxInfusionGroup.getCycle() <= CommonConstant.DEFAULT_0){
						throw new BusinessFailException("用药周期必须大于"+ CommonConstant.DEFAULT_0);
					}
				}
				//滴注速度
				String ivDripRate = rxInfusionGroup.getIvDripRate();
				if(isMedical || StringUtil.isNotBlank(ivDripRate)){
					if(StringUtil.isBlank(rxInfusionGroup.getIvDripRate())){
						throw new BusinessFailException("滴注速度不能为空");
					}
					if(!InfusionIvDripRateEnum.isValue(rxInfusionGroup.getIvDripRate())){
						throw new BusinessFailException("滴注速度错误");
					}
				}
				Integer subtotal = CommonConstant.DEFAULT_0;
				for(RxInfusionGroupDetail groupDetail : detailList){
					//检查药品
					Long storageId = rxInfusion.getStorageId();
					if(StringUtil.isBlank(storageId)){
						storageId = defaultStorageId;
					}
					String key = storageId + "_" + groupDetail.getDrugId();
					StockDrugProfileDetailVo stockDrugProfile = drugProfileMap.get(key);
					if(stockDrugProfile == null){
						throw new BusinessFailException("药品不存在");
					}
					BeanUtils.copyProperties(stockDrugProfile,groupDetail);
					//剂量用药品的最小单位
					groupDetail.setDosageUnit(stockDrugProfile.getMinPackUnit());
					groupDetail.setDosageUnitText(stockDrugProfile.getMinPackUnitText());
					if(YesOrNoEnum.YES.getValue().equals(stockDrugProfile.getIsSplit())){
						groupDetail.setTotalOutQtyUnit(stockDrugProfile.getMinPackUnit());
						groupDetail.setTotalOutQtyUnitText(stockDrugProfile.getMinPackUnitText());
					}else {
						groupDetail.setTotalOutQtyUnit(stockDrugProfile.getPackUnit());
						groupDetail.setTotalOutQtyUnitText(stockDrugProfile.getPackUnitText());
					}
					if(StringUtil.isNotBlank(groupDetail.getSkinTest())){
						if(!SkinTestEnum.isValue(groupDetail.getSkinTest())){
							throw new BusinessFailException("是否皮试错误！");
						}
					}
					//用量
					BigDecimal dosage = groupDetail.getDosage();
					if(isMedical || dosage != null){
						if(groupDetail.getDosage() == null || BigDecimalUtils.lt(groupDetail.getDosage(),BigDecimal.ZERO)){
							throw new BusinessFailException("用量必须大于"+ CommonConstant.DEFAULT_0);
						}
					}
					//总出库量
					Integer totalOutQty = groupDetail.getTotalOutQty();
					if(isMedical || totalOutQty != null){
//						Integer totalOutQty = RxUtil.calculateTotalDose(groupDetail.getDosage(), dictFrequencyVo.getFrequencyTimes(), rxInfusionGroup.getCycle(), stockDrugProfile.getIsMinSplit());
//						groupDetail.setTotalOutQty(totalOutQty);
						//计算总出库量
						if(groupDetail.getTotalOutQty() == null || groupDetail.getTotalOutQty() <= CommonConstant.DEFAULT_0){
							throw new BusinessFailException("总量必须大于"+ CommonConstant.DEFAULT_0);
						}
						groupDetail.setSubtotal(RxUtil.calculatePrice(groupDetail.getTotalOutQty(),stockDrugProfile.getMinPackQty(),stockDrugProfile.getIsSplit(),stockDrugProfile.getPrice(),stockDrugProfile.getSplitPrice()));
						subtotal = subtotal + groupDetail.getSubtotal();
					}

//                        if(StringUtil.isNotBlank(groupDetail.getRemark())){
//                            boolean remarkValue = clinicDictService.isRemarkValue(RxTypeEnum.INFUSION.getValue(), groupDetail.getRemark());
//                            if(!remarkValue){
//                                throw new BusinessFailException("输注处方备注错误");
//                            }
//                        }

//
//					if(YesOrNoEnum.YES.getValue().equals(isMedical)){
//						//门诊需要验证库存不足
//						if(!validateStorage(stockDrugProfile,groupDetail.getTotalOutQty())){
//							throw new BusinessFailException(stockDrugProfile.getDrugName() + "库存不足！");
//						}
//					}
				}
				rxInfusionGroup.setSubtotal(subtotal);
				totalAmount = totalAmount + rxInfusionGroup.getSubtotal();
			}
			rxInfusion.setTotalAmount(totalAmount);
		}
	}

	/**
	 * 校验中药处方
	 * @param drugList
	 */
	public void validateDrugList(boolean isMedical,List<RxDrug> drugList,Long defaultStorageId,Map<String, StockDrugProfileDetailVo> drugProfileMap) {
		int sort = CommonConstant.DEFAULT_0;
		for(RxDrug rxDrug : drugList){
			sort = sort + CommonConstant.DEFAULT_1;
			if(StringUtil.isBlank(rxDrug.getRxName())){
				rxDrug.setRxName(String.format(Constants.DEFAULT_RX_DRUG_NAME,StringUtil.toChinese(sort)));
			}
			if(isMedical && StringUtil.isBlank(rxDrug.getStorageId())){
				throw new BusinessFailException("请先选择药库！");
			}
			List<RxDrugDetail> detailList = rxDrug.getDetailList();
			if(CollectionUtils.isEmpty(detailList)){
				throw new BusinessFailException("至少添加一个药品！");
			}
			if(!CollectionUtils.isEmpty(detailList)){
				Integer totalAmount = CommonConstant.DEFAULT_0;
				for(RxDrugDetail rxDrugDetail : detailList){
					//检查药品
					Long storageId = rxDrug.getStorageId();
					if(StringUtil.isBlank(storageId)){
						storageId = defaultStorageId;
					}
					String key = storageId + "_" + rxDrugDetail.getDrugId();
					StockDrugProfileDetailVo stockDrugProfile = drugProfileMap.get(key);
					if(stockDrugProfile == null){
						throw new BusinessFailException("药品不存在");
					}
					BeanUtils.copyProperties(stockDrugProfile,rxDrugDetail);
					//剂量用药品的最小单位
					rxDrugDetail.setDosageUnit(stockDrugProfile.getMinPackUnit());
					rxDrugDetail.setDosageUnitText(stockDrugProfile.getMinPackUnitText());
					//根据药品是否可以拆分来显示出库的单位
					if(YesOrNoEnum.YES.getValue().equals(stockDrugProfile.getIsSplit())){
						rxDrugDetail.setTotalOutQtyUnit(stockDrugProfile.getMinPackUnit());
						rxDrugDetail.setTotalOutQtyUnitText(stockDrugProfile.getMinPackUnitText());
					}else {
						rxDrugDetail.setTotalOutQtyUnit(stockDrugProfile.getPackUnit());
						rxDrugDetail.setTotalOutQtyUnitText(stockDrugProfile.getPackUnitText());
					}
					//用法 餐前服/餐后服
					String usageCode = rxDrugDetail.getUsageCode();
					if(isMedical || StringUtil.isNotBlank(usageCode)){
						if(StringUtil.isBlank(usageCode)){
							throw new BusinessFailException("用法不能为空");
						}
						DictUsageVo dictUsageVo = clinicDictService.getUsageValue(RxTypeEnum.DRUG.getValue(),usageCode);
						if(dictUsageVo == null){
							throw new BusinessFailException("用法错误");
						}
						rxDrugDetail.setUsageCodeText(dictUsageVo.getUsageName());
					}
					//周期 3天
					Integer cycle =  rxDrugDetail.getCycle();
					if(isMedical || cycle != null){
						if(cycle == null || cycle <= CommonConstant.DEFAULT_0){
							throw new BusinessFailException("用药周期必须大于"+ CommonConstant.DEFAULT_0);
						}
					}
					//用量 1.3ml
					BigDecimal dosage = rxDrugDetail.getDosage();
					if(isMedical || dosage != null){
						if(dosage == null || BigDecimalUtils.lt(dosage, BigDecimal.ZERO)){
							throw new BusinessFailException("用量必须大于"+ CommonConstant.DEFAULT_0);
						}
					}
					//频率 一天一次
					String frequencyCode = rxDrugDetail.getFrequencyCode();
					if(isMedical || StringUtil.isNotBlank(frequencyCode)){
						if(StringUtil.isBlank(frequencyCode)){
							throw new BusinessFailException("频率不能为空");
						}
						DictFrequencyVo dictFrequencyVo = clinicDictService.getCacheFrequency(frequencyCode);
						if(dictFrequencyVo == null){
							throw new BusinessFailException("频率不存在");
						}
						rxDrugDetail.setFrequencyCodeText(dictFrequencyVo.getFrequencyName());
						rxDrugDetail.setCycleUnit(dictFrequencyVo.getCycleUnit());
						rxDrugDetail.setCycleUnitText(CycleUnitEnum.getText(dictFrequencyVo.getCycleUnit()));
					}
					//总量
					Integer totalOutQty = rxDrugDetail.getTotalOutQty();
					if(isMedical || totalOutQty != null){
//						Integer totalOutQty = RxUtil.calculateTotalDose(
//							rxDrugDetail.getDosage(),
//							dictFrequencyVo.getFrequencyTimes(),
//							rxDrugDetail.getCycle(),
//							stockDrugProfile.getIsMinSplit());
						if(totalOutQty == null || totalOutQty <= CommonConstant.DEFAULT_0){
							throw new BusinessFailException("总量必须大于"+ CommonConstant.DEFAULT_0);
						}
						//计算价格
						rxDrugDetail.setSubtotal(RxUtil.calculatePrice(totalOutQty,stockDrugProfile.getMinPackQty(),stockDrugProfile.getIsSplit(),stockDrugProfile.getPrice(),stockDrugProfile.getSplitPrice()));
						totalAmount = totalAmount + rxDrugDetail.getSubtotal();
					}
//					//门诊需要验证库存（库存不足也可以下单，仅仅是提醒）
//					if(!validateStorage(stockDrugProfile,rxDrugDetail.getTotalOutQty())){
//						throw new BusinessFailException(stockDrugProfile.getDrugName()+"库存不足！");
//					}


//                        if(StringUtil.isNotBlank(templateRxDrugDetail.getRemark())){
//                            boolean remarkValue = clinicDictService.isRemarkValue(RxTypeEnum.DRUG.getValue(), templateRxDrugDetail.getRemark());
//                            if(!remarkValue){
//                                throw new BusinessFailException("成药处方备注错误");
//                            }
//                        }
				}
				rxDrug.setTotalAmount(totalAmount);
			}
		}
	}



	/**
	 * 验证查验项目的公共方法
	 * @param detailList
	 */
	public void validateMedicalExam(String isMedical,List<ExamDetail> detailList){
		if(CollectionUtils.isEmpty(detailList)){
			throw new BusinessFailException("请配置查验项目");
		}
		List<Long> projectIds = detailList.stream()
				.map(ExamDetail::getProjectId)
				.filter(Objects::nonNull)
				.distinct()
				.collect(Collectors.toList());
		if (CollectionUtils.isEmpty(projectIds)) {
			throw new BusinessFailException("请配置查验项目");
		}
		// 查询所有有效项目（一次查库）
		List<ClinicProjectFee> projectList = projectFeeService.getEnabledClinicProjectFeeList(projectIds, ProjectCategoryEnum.getExamList());
		if(CollectionUtils.isEmpty(projectList)){
			throw new BusinessFailException("请配置查验项目");
		}
		// 转成 Map 方便后续判断是否存在
		Map<Long, ClinicProjectFee> projectMap = projectList.stream()
				.collect(Collectors.toMap(ClinicProjectFee::getProjectId, Function.identity()));
		//是否为门诊
		boolean medicalFlag = YesOrNoEnum.YES.getValue().equals(isMedical);
		// 遍历 detailList 做校验
		for (ExamDetail examDetail : detailList) {
			ClinicProjectFee clinicProjectFee = projectMap.get(examDetail.getProjectId());
			if (clinicProjectFee == null) {
				throw new BusinessFailException("查验项目不存在");
			}
			examDetail.setProjectName(clinicProjectFee.getProjectName());
			examDetail.setPrice(clinicProjectFee.getPrice());
			examDetail.setProjectCategory(clinicProjectFee.getProjectCategory());
			examDetail.setProjectType(clinicProjectFee.getProjectType());
			examDetail.setPrice(clinicProjectFee.getPrice());
			examDetail.setSampleType(clinicProjectFee.getSampleType());
			examDetail.setTotalOutQtyUnit(clinicProjectFee.getUnit());
			examDetail.setTotalOutQtyUnitText(clinicProjectFee.getUnitText());
			//频率 1天1次
			String frequencyCode = examDetail.getFrequencyCode();
			//周期 5天
			Integer cycle = examDetail.getCycle();
			//总量=评率*周期
			Integer totalOutQty = examDetail.getTotalOutQty();
			if(medicalFlag || StringUtil.isNotBlank(examDetail.getFrequencyCode())){
				//如果是门诊或者是模板给了频率
				if(StringUtil.isBlank(frequencyCode)){
					throw new BusinessFailException("频率不能为空");
				}
				DictFrequencyVo dictFrequencyVo = clinicDictService.getCacheFrequency(frequencyCode);
				if(dictFrequencyVo == null){
					throw new BusinessFailException("频率不存在");
				}
				examDetail.setFrequencyCodeText(dictFrequencyVo.getFrequencyName());
				examDetail.setCycleUnit(dictFrequencyVo.getCycleUnit());
				examDetail.setCycleUnitText(CycleUnitEnum.getText(dictFrequencyVo.getCycleUnit()));
			}
			if(medicalFlag || cycle != null){
				//如果是门诊或者是模板给了周期
				if(cycle == null || cycle <= CommonConstant.DEFAULT_0){
					throw new BusinessFailException("用药周期必须大于"+ CommonConstant.DEFAULT_0);
				}
			}
			if(medicalFlag || totalOutQty != null){
				//如果是门诊或者模板给了总量
				if(totalOutQty == null || totalOutQty <= CommonConstant.DEFAULT_0){
					throw new BusinessFailException("总量必须大于"+ CommonConstant.DEFAULT_0);
				}
				examDetail.setSubtotal(examDetail.getPrice() * examDetail.getTotalOutQty());
			}
		}
	}


	/**
	 * 验证病历字段的公共方法
	 * @param fieldList
	 */
	public void validateMedicalField(String isMedical,String operateType,List<MedicalFieldDetail> fieldList){
		if(CollectionUtils.isEmpty(fieldList)){
			throw new BusinessFailException("请配置病历字段");
		}
		//判断哪些 field 不在默认字段里
		checkDefaultFieldList(isMedical,operateType,fieldList);
		//根据code查询字段列表
		// 1. 提取并校验 fieldId
		List<Long> fieldIdList = fieldList.stream()
				.map(MedicalFieldDetail::getFieldId)
				.peek(fieldId -> {
					if (fieldId == null) {
						throw new BusinessFailException("请配置病历字段");
					}
				})
				.collect(Collectors.toList());
		List<MedicalField> medicalFieldList = medicalFieldService.getFieldListByIdList(fieldIdList);
		if(CollectionUtils.isEmpty(medicalFieldList)){
			throw new BusinessFailException("请配置病历字段");
		}
		Map<Long, MedicalField> medicalFieldMap = medicalFieldList.stream()
				.collect(Collectors.toMap(MedicalField::getFieldId, Function.identity()));
		//检查字段
		for (MedicalFieldDetail medicalFieldDetail : fieldList) {
			MedicalField medicalField = medicalFieldMap.get(medicalFieldDetail.getFieldId());
			if (medicalField == null) {
				throw new BusinessFailException("病历字段不存在");
			}
			medicalFieldDetail.setFieldName(medicalField.getFieldName());
			medicalFieldDetail.setFieldCode(medicalField.getFieldCode());
			medicalFieldDetail.setFieldType(medicalField.getFieldType());
			medicalFieldDetail.setFieldScope(medicalField.getFieldScope());
			medicalFieldDetail.setFieldStyle(medicalField.getFieldStyle());
			medicalFieldDetail.setIsRequired(medicalField.getIsRequired());
			medicalFieldDetail.setIsRecom(medicalField.getIsRecom());
			medicalFieldDetail.setIsVoice(medicalField.getIsVoice());
			medicalFieldDetail.setIsImage(medicalField.getIsImage());
			medicalFieldDetail.setIsPulse(medicalField.getIsPulse());
			medicalFieldDetail.setIsCycle(medicalField.getIsCycle());
			medicalFieldDetail.setIsDefault(medicalField.getIsDefault());
			medicalFieldDetail.setSortNum(medicalField.getSortNum());
		}
	}

	/**
	 * 病历默认字段检查
	 * @param fieldList
	 */
	public void checkDefaultFieldList(String isMedical,String operateType,List<MedicalFieldDetail> fieldList) {
		if(YesOrNoEnum.YES.getValue().equals(isMedical) && OperateTypeEnum.EDIT.getValue().equals(operateType)){
			List<MedicalField> defaultFieldList = medicalFieldService.getRequiredFieldList();
			// 转成 Map：fieldId -> fieldName，便于提示用
			Map<Long, String> defaultFieldMap = defaultFieldList.stream()
					.collect(Collectors.toMap(MedicalField::getFieldId, MedicalField::getFieldName));
			//从web端给过来的
			Map<Long, MedicalFieldDetail> fieldMap = fieldList.stream()
					.collect(Collectors.toMap(
							MedicalFieldDetail::getFieldId,   // key
							Function.identity()               // value 为对象本身
					));
			for (Map.Entry<Long, String> entry : defaultFieldMap.entrySet()) {
				Long filedId = entry.getKey();
				MedicalFieldDetail medicalFieldDetail = fieldMap.get(filedId);
				if(medicalFieldDetail == null){
					throw new BusinessFailException(entry.getValue()+"必须选择！");
				}
				if(StringUtil.isBlank(medicalFieldDetail.getFieldValue())){
					throw new BusinessFailException("请填写"+entry.getValue()+"！");
				}
			}
		}

	}

}
